package customprogressindicator;

import java.applet.AppletStub;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import netscape.javascript.JSObject;

public class TestCustomProgress {

	// TestCase information
	private static final String TESTCASE_VALIDATING2 = "testcaseValidating2";
	private static final String TESTCASE_PROGRESS2 = "testcaseProgress2";
	private static final String TESTCASE_VALIDATING1_ENTRIES = "testcaseValidating1Entries";
	private static final String TESTCASE_VALIDATING1_JAR1_NAME = "testcaseValidating1Jar1Name";
	private static final String TESTCASE_VALIDATING1 = "testcaseValidating1";
	private static final String TESTCASE_PROGRESS1_JAR1_SIZE = "testcaseProgress1Jar1Size";
	private static final String TESTCASE_PROGRESS1_JAR1_NAME = "testcaseProgress1Jar1Name";
	private static final String TESTCASE_PROGRESS1 = "testcaseProgress1";
	private static final String TESTCASE_PARAM_NAME1 = "testcaseParamName1";
	private static final String TESTCASE_PARAM = "testcaseParam";

	private static final String FAIL = "FAIL";
	private static final String PASS = "PASS";
	private static final String TAB = "\t";

	public List<String> testCaseResult;

	// Flags to tag whether the testcases are completed
	public boolean testCaseProgress2Success = true;
	public boolean testCaseValidating2Success = true;
	public boolean testcaseProgress1IsDone;
	public boolean testcaseValidating1IsDone;

	Properties testProp = null;
	JSObject window = null;

	public TestCustomProgress() {
		testCaseResult = new ArrayList<String>();
		loadAppletTestProperties();
	}

	private void loadAppletTestProperties() {
		testProp = new Properties();
		InputStream input = null;
		try {
			String filename = "config/applettest.properties";
			System.out.println(filename);
			URL urlToProps = this.getClass().getResource(filename);
			URLConnection connection = urlToProps.openConnection();
			connection.setConnectTimeout(5000);
			input = connection.getInputStream();
			if (input == null) {
				System.out.println("Sorry, unable to find " + filename);
				return;
			}

			testProp.load(input);

		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			if (input != null) {
				try {
					input.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}

	public void init(AppletStub appletStub) {
		testAppletParameter(appletStub);
	}

	private void testAppletParameter(AppletStub appletStub) {
		String testCaseId = testProp.getProperty(TESTCASE_PARAM);
		String paramName1 = testProp.getProperty(TESTCASE_PARAM_NAME1);
		String result = null;
		String comments = null;

		if (appletStub.getParameter(paramName1) == null) {
			result = FAIL;
			comments = "Unable to access the applet parameters from custom progress bar";
		} else {
			result = PASS;
			comments = new StringBuilder(paramName1).append("=")
					.append(appletStub.getParameter(paramName1)).toString();
		}
		testCaseResult.add(new StringBuilder(testCaseId).append(TAB)
				.append(result).append(TAB).append(comments).append(TAB)
				.toString());
	}

	public void progress(URL url, String version, long readSoFar, long total,
			int overallPercent) {
		if (url != null) {
			String testCaseId = testProp.getProperty(TESTCASE_PROGRESS1);
			String testCase1InputJarName = testProp
					.getProperty(TESTCASE_PROGRESS1_JAR1_NAME);
			String testCase1InputJarSize = testProp
					.getProperty(TESTCASE_PROGRESS1_JAR1_SIZE);
			
			if (testCase1InputJarName != null && testCase1InputJarSize != null
					&& url.toString().endsWith(testCase1InputJarName)
					&& !testcaseProgress1IsDone) {
				testcaseProgress1IsDone = true;
				long size = Long.parseLong(testCase1InputJarSize);
				if (size == total) {
					testCaseResult.add(new StringBuilder(testCaseId)
							.append(TAB).append(PASS).append(TAB)
							.append(url.toString()).append(" has ")
							.append(total).append(" bytes ").append(TAB)
							.toString());
				} else {
					testCaseResult.add(new StringBuilder(testCaseId)
							.append(TAB).append(FAIL).append(TAB)
							.append(url.toString()).append(" has ")
							.append(total)
							.append(" bytes but downloadserivce shows ")
							.append(total).append(" bytes").append(TAB)
							.toString());
				}
			}
			
			if (testCaseProgress2Success && readSoFar > total) {
				testCaseProgress2Success = false;
				testCaseResult.add(new StringBuilder(testProp
						.getProperty(TESTCASE_PROGRESS2)).append(TAB)
						.append(FAIL).append(TAB).append(url.toString())
						.append(" gets readSoFar > total").append(TAB)
						.toString());
			}

		}

	}

	public void upgradingArchive(URL url, String version, int patchPercent,
			int overallPercent) {
		// TODO Auto-generated method stub

	}

	public void validating(URL url, String version, long entry, long total,
			int overallPercent) {
		if (overallPercent == 100 && testCaseResult != null) {
			publishTestResult();
		}
		if (url != null) {
			String testCaseId = testProp.getProperty(TESTCASE_VALIDATING1);
			String testCase1InputJarName = testProp
					.getProperty(TESTCASE_VALIDATING1_JAR1_NAME);
			String testCase1InputJarEntries = testProp
					.getProperty(TESTCASE_VALIDATING1_ENTRIES);
			if (testCase1InputJarName != null
					&& testCase1InputJarEntries != null
					&& url.toString().endsWith(testCase1InputJarName)
					&& !testcaseValidating1IsDone) {
				testcaseValidating1IsDone = true;
				long entries = Long.parseLong(testCase1InputJarEntries);
				if (entries == total) {
					testCaseResult.add(new StringBuilder(testCaseId)
							.append(TAB).append(PASS).append(TAB)
							.append(url.toString()).append(" has ")
							.append(total).append(" entries ").append(TAB)
							.toString());
				} else {
					testCaseResult.add(new StringBuilder(testCaseId)
							.append(TAB).append(FAIL).append(TAB)
							.append(url.toString()).append(" has ")
							.append(total)
							.append(" entries but downloadserivce shows ")
							.append(total).append(" entries").append(TAB)
							.toString());
				}
			}
			if (testCaseValidating2Success && entry > total) {
				testCaseValidating2Success = false;
				testCaseResult
						.add(new StringBuilder(testProp
								.getProperty(TESTCASE_VALIDATING2)).append(TAB)
								.append(FAIL).append(TAB)
								.append(url.toString())
								.append(" gets entries > total").append(TAB)
								.toString());
			}

		}

	}

	private void publishTestResult() {
		finalizeTestcases();
		if (window != null && testCaseResult != null) {
			try {
				window.call("publicTetResult", testCaseResult.toArray());
			} catch (Exception e) {
				// print stack trace for debuging purpose
				e.printStackTrace();
				
			}
		}
		testCaseResult = null;
	}

	private void finalizeTestcases() {
		if (testCaseProgress2Success) {
			testCaseResult.add(new StringBuilder(testProp
					.getProperty(TESTCASE_PROGRESS2)).append(TAB).append(PASS)
					.append(TAB).append(" --- ").append(TAB).toString());
		}
		if (testCaseValidating2Success) {
			testCaseResult.add(new StringBuilder(testProp
					.getProperty(TESTCASE_VALIDATING2)).append(TAB)
					.append(PASS).append(TAB).append(" --- ").append(TAB)
					.toString());
		}
	}

	public void setJSObject(JSObject newWindow) {
		window = newWindow;
	}

}
